package com.ch.ebusiness.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.access.AccessDeniedHandler;

import javax.annotation.Resource;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @Description TODO
 * @Author MarsYr
 * @Date 2021/7/13 9:41
 * @Version 1.0
 */

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    
    @Resource
    UserDetailsService userDetailsService;
    
    @Bean
    public BCryptPasswordEncoder bCryptPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }
    
    @Override
    protected void configure(AuthenticationManagerBuilder builder) throws Exception {
        //builder
        //        .inMemoryAuthentication()        // 开启在内存中进行身份验证（开发时暂用）
        //        .passwordEncoder(bCryptPasswordEncoder())
        //        .withUser("13033268820")                 // 设置用户名
        //        .password(new BCryptPasswordEncoder().encode("123456"))        // 设置密码
        //        .roles("ADMIN");                 // 设置权限
        //
        builder
                .userDetailsService(userDetailsService)
                .passwordEncoder(new BCryptPasswordEncoder());
        
    }
    
    
    @Override
    protected void configure(HttpSecurity security) throws Exception {
        String[] permitUrls = {"/css/**", "/img/**", "/in/**", "/jin/**", "/fonts/**", "/images/**",
                "/js/**", "/user/toLogin", "/user/toRegister", "/admin/**", "/", "/selectUser", "/selectUserUpdate",
                "/goodsDetail", "/search", "/validateCode", "/goods/**", "/type/**", "/selectUserDelete", "/deleteUser",
                "/updateUser", "/user/userLogin", "/updateUserDetail", "/selectOrder", "/selectOrderDelete", "/deleteOrder",
                "/user/send/message", "/loginOut"};
        security
                .authorizeRequests()        // 表示对请求进行授权
                .antMatchers(permitUrls)    // 传入的ant风格的url
                .permitAll()                // 允许上面的所有请求，不需要认证
                .anyRequest()               // 其他未设置的全部请求
                .authenticated()            // 表示需要认证
                .and()
                .csrf()         // 设置csrf
                .disable()      // 关闭csrf
                .formLogin()// 开启表单登录功能
                .loginPage("/user/toLogin")    // 指定登陆页面
                .usernameParameter("phoneNumber")             // 设置表单中对应用户名的标签的name属性名
                .passwordParameter("bpwd")
                //.loginProcessingUrl("/admin/do/login.html")  // 设置登录请求的提交地址
                .loginProcessingUrl("/user/userLogin")  // 设置登录请求的提交地址
                .defaultSuccessUrl("/user/ok")    // 设置登陆成功后前往的地址
                .permitAll()
                .and()
                .logout()                                       // 开启退出登录功能
                .logoutUrl("/loginOut")          // 设置退出登录的url
                .logoutSuccessUrl("/admin/login")   // 设置退出成功后前往的页面
                .and()
                .exceptionHandling()
                .accessDeniedHandler(new AccessDeniedHandler() {
                    @Override
                    public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AccessDeniedException e) throws IOException, ServletException {
                        httpServletRequest.setAttribute("mymessage", new Exception("抱歉，您没有权限访问该资源！"));
                        httpServletRequest.getRequestDispatcher("/myError").forward(httpServletRequest, httpServletResponse);
                    }
                })
        ;
        
    }
}

